package com.fulin.thread.condition;

import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class BatchCache {
    private static Lock lock = new ReentrantLock(true);
    private static Condition pc = lock.newCondition();
    private static Condition cc = lock.newCondition();

    private static Set<Integer> pool = new HashSet<>(1024);
    private static AtomicInteger count = new AtomicInteger(0);
    private static int result = 0;

    private static final int size = 200000;

    public static void main(String[] args) throws InterruptedException {
        new Thread(BatchCache::take,"c").start();

        new Thread(()->{
            System.out.println("p1 start");
            for(int i = 1;i <= size;i++){
                put(i);
            }
            System.out.println("p1 add " + size);
        },"p1").start();

        new Thread(()->{
            System.out.println("p2 start");
            for(int i = size + 1;i <= size * 2 + 1;i++){
                put(i);
            }
            System.out.println("p2 add " + size);
        },"p2").start();
    }

    private static void put(int i){
        String name = Thread.currentThread().getName();
        lock.lock();
        try {
            while(pool.size() == size){
                pc.await();
            }
//            System.out.println(name + "增加 1");
            cc.signalAll();
            pool.add(i);
        }catch (Exception e){
            e.printStackTrace();
        }finally{
            lock.unlock();
        }
    }

    private static void take(){
        String name = Thread.currentThread().getName();
        while(true) {
            lock.lock();
            try {
                while (pool.size() != size) {
                    cc.await();
                }
                TimeUnit.MILLISECONDS.sleep(20);
                System.out.println(name + "减少 " + pool.size());
                result += pool.size();
                pool.clear();
                pc.signalAll();
                System.out.println("result "+result);
            } catch (Exception e) {
                System.out.println("take 出现异常");
            } finally {
                lock.unlock();
            }
        }
    }


}
